﻿#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <Tlhelp32.h>
#include "D3dDraw.h"
#define p 3.1415926535


D3dDraw			   Dw;
HANDLE			   hProcess;
HWND			   han;
static int		   i;
static DWORD	   PID;
static HANDLE      proHandle;
static HMODULE     ServerHandle;
static HMODULE     engineHandle;
static HMODULE     clientHandle;
static DWORD	   mBase;
static DWORD	   dBase;
static DWORD	   MatrixBase;
static DWORD       WideAngle;
static DWORD       HeightAngle;
static bool		   autoAim;
DWORD			   myteam;						//本人阵营
D3D				   M;							//本人坐标
D3D				   D;							//敌人坐标
D3D				   TE;
DWORD              enemiesNum{};				//敌人数量
DWORD              clientDBase;					//本人基址
DWORD		       clientenemBase{};			//客户端敌人基地址
DWORD              clientenemDrawBonesLBase{};  //客户端敌人骨骼地址
DWORD              clientenemDrawBonesL{};		//客户端敌人骨骼
DWORD		       enemDrawBonesL;				//敌人骨骼
D3DCOLOR red = D3DCOLOR_ARGB(255, 255, 0, 0);
D3DCOLOR blue = D3DCOLOR_ARGB(255, 0, 0, 255);


DWORD GetModuleBaseAddress(const TCHAR* LPSTRModuleName, DWORD __DwordProcessId)
{
	MODULEENTRY32 lpModuleEntry = { 0 };
	HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, __DwordProcessId);
	if (!hSnapShot)
		return NULL;
	lpModuleEntry.dwSize = sizeof(lpModuleEntry);
	BOOL __RunModule = Module32First(hSnapShot, &lpModuleEntry);
	while (__RunModule)
	{
		if (!_tcscmp(lpModuleEntry.szModule, LPSTRModuleName))
		{
			CloseHandle(hSnapShot);
			return (DWORD)lpModuleEntry.modBaseAddr;
		}
		__RunModule = Module32Next(hSnapShot, &lpModuleEntry);
	}
	CloseHandle(hSnapShot);
	return NULL;
}


float Take_CollimatorDistance(float beadx, float beady, float objx, float objy)
{
	float DX, DY, Dd;

	DX = beadx - objx;
	DY = beady - objy;
	Dd = sqrt(DX * DX + DY * DY);
	return Dd;
}

float Take_EnemyDistance(D3D m, D3D d)
{
	float DX, DY, Dd;
	DX = m.x - d.x;
	DY = m.y - d.y;
	Dd = sqrt(DX * DX + DY * DY);
	return Dd;
}

D2D Aim(D3D x, D3D y)
{
	D2D mouse;
	D3D aimmouse_;
	aimmouse_.x = x.x - y.x;
	aimmouse_.y = x.y - y.y;
	aimmouse_.z = x.z - y.z + 63;
	if (aimmouse_.x >= 0 && aimmouse_.y >= 0)
	{
		mouse.x = atan((aimmouse_.y / aimmouse_.x)) / p * 180 - 180;
	}
	if (aimmouse_.x <= 0 && aimmouse_.y >= 0)
	{
		mouse.x = atan((aimmouse_.y / aimmouse_.x)) / p * 180;
	}
	if (aimmouse_.x <= 0 && aimmouse_.y <= 0)
	{
		mouse.x = atan((aimmouse_.y / aimmouse_.x)) / p * 180;
	}
	if (aimmouse_.x >= 0 && aimmouse_.y <= 0)
	{
		mouse.x = atan((aimmouse_.y / aimmouse_.x)) / p * 180 + 180;
	}
	mouse.y = atan(aimmouse_.z / sqrt(aimmouse_.x * aimmouse_.x + aimmouse_.y * aimmouse_.y)) / p * 180;
	return mouse;
}


void DrawBonesO(float ViewWorld[4][4], int addr, int Head);
void DrawBonesL(float ViewWorld[4][4], int addr, int start, int end);
void Draws()
{
	/**/
	float       ViewWorld[4][4]{};
	D3D			Aiminfo;
	D2D			AimMose;
	//骨骼方框
	float BonesScaling;		//缩放比例
	float BonesBoxH;			//方框高度
	float BonesBoxW;			//方框宽度
	float Bonesx;
	float Bonesy;
	float Bonesy2;
	float Bonesz;

	/*坐标方框
	float* x = new float[enemiesNum * sizeof(float)];
	float* y = new float[enemiesNum * sizeof(float)];
	float* y2 = new float[enemiesNum * sizeof(float)];
	float* z = new float[enemiesNum * sizeof(float)];
	float* scaling = new float[enemiesNum * sizeof(float)];				//缩放比例
	float* boxH = new float[enemiesNum * sizeof(float)];				//方框高度
	float* boxW = new float[enemiesNum * sizeof(float)];				//方框宽度
	*/
	float EnemySightDistance;	//敌人准星距离
	float EnemyD3dDistance;		//敌人D3D距离
	float EnemyDistance;		//敌人骨骼距离
	float EnemySideDis{};			//敌人骨骼D3D差值
	DWORD EnemyHealth;			//敌人血量
	DWORD EnemyCamp;			//敌人阵营
	float  AimSize = 300;
	char buf[100]{};
	char buf2[100]{};
	char buf3[100]{};
	WideAngle = Dw.GetWidth() / 2;
	HeightAngle = Dw.GetHeight() / 2;
	ReadProcessMemory(proHandle, (LPCVOID)MatrixBase, ViewWorld, sizeof(float) * 16, NULL);



	//Dw.DrawText_(20, 100, "易道云信息技术研究院", x);

	Dw.DrawStart();
	// ----------------本人数据-----------------------------------------
	ReadProcessMemory(proHandle, (LPCVOID)((DWORD)ServerHandle + 0x4F2FEC), &mBase, sizeof(DWORD), NULL);
	ReadProcessMemory(proHandle, (LPCVOID)(mBase + 0x1F4), &myteam, sizeof(DWORD), NULL);
	ReadProcessMemory(proHandle, (LPCVOID)(mBase + 0x280), &M, sizeof(float) * 3, NULL);
	//----------------本人数据-----------------------------------------
	ReadProcessMemory(proHandle, (LPCVOID)((DWORD)ServerHandle + 0x588878), &enemiesNum, sizeof(DWORD), NULL);

	ReadProcessMemory(proHandle, (LPCVOID)((DWORD)clientHandle + 0x498558), &clientenemBase, sizeof(DWORD), NULL);
	for (i = 0; i < enemiesNum; i++)
	{
		// ----------------骨骼数据-----------------------------------------
		ReadProcessMemory(proHandle, (LPCVOID)(clientenemBase + (4 + ((i + 1) - 1) * 2) * 8 + 4), &clientenemDrawBonesL, sizeof(DWORD), NULL);//4*8+4
		ReadProcessMemory(proHandle, (LPCVOID)(clientenemDrawBonesL + 0x578), &clientenemDrawBonesLBase, sizeof(DWORD), NULL);	//578
		enemDrawBonesL = clientenemDrawBonesLBase + (15 - 1) * 48 + 12;
		ReadProcessMemory(proHandle, (LPCVOID)enemDrawBonesL, &TE.x, sizeof(float), NULL);
		ReadProcessMemory(proHandle, (LPCVOID)(enemDrawBonesL + 16), &TE.y, sizeof(float), NULL);
		ReadProcessMemory(proHandle, (LPCVOID)(enemDrawBonesL + 32), &TE.z, sizeof(float), NULL);
		// ----------------敌人数据-----------------------------------------
		ReadProcessMemory(proHandle, (LPCVOID)((DWORD)ServerHandle + 0x4F2FFC + (i * 16)), &dBase, sizeof(DWORD), NULL);
		ReadProcessMemory(proHandle, (LPCVOID)(dBase + 0x1F4), &EnemyCamp, sizeof(DWORD), NULL);
		ReadProcessMemory(proHandle, (LPCVOID)(dBase + 0x280), &D, sizeof(float) * 3, NULL);
		ReadProcessMemory(proHandle, (LPCVOID)(dBase + 0xE4), &EnemyHealth, sizeof(float), NULL);
		//----------------敌人数据-----------------------------------------
		// 坐标方框
		//z[i] = ViewWorld[2][0] * D.x + ViewWorld[2][1] * D.y + ViewWorld[2][2] * D.z + ViewWorld[2][3];
		//scaling[i] = 1 / z[i];
		//if ((z[i] < 0)) continue;
		//x[i] = WideAngle + (ViewWorld[0][0] * D.x + ViewWorld[0][1] * D.y + ViewWorld[0][2] * D.z + ViewWorld[0][3]) * scaling[i] * WideAngle;
		//y[i] = HeightAngle - (ViewWorld[1][0] * D.x + ViewWorld[1][1] * D.y + ViewWorld[1][2] * D.z + ViewWorld[1][3]) * scaling[i] * HeightAngle;
		//y2[i] = HeightAngle - (ViewWorld[1][0] * D.x + ViewWorld[1][1] * D.y + ViewWorld[1][2] * (D.z + 70) + ViewWorld[1][3]) * scaling[i] * HeightAngle;
		//boxH[i] = (y[i] - y2[i]) + 10;
		//boxW[i] = boxH[i] * 0.526515151552;
		//EnemySightDistance[i] = Take_CollimatorDistance(WideAngle, HeightAngle, x[i], y[i]);
		//EnemyDistance[i] = floor(Take_EnemyDistance(M, D) / 10);

		//骨骼方框
		Bonesz = ViewWorld[2][0] * TE.x + ViewWorld[2][1] * TE.y + ViewWorld[2][2] * TE.z + ViewWorld[2][3] + 5;
		BonesScaling = 1 / Bonesz;
		if ((Bonesz < 0) || (EnemyCamp == myteam) || (EnemyHealth < 0)) continue;
		Bonesx = WideAngle + (ViewWorld[0][0] * TE.x + ViewWorld[0][1] * TE.y + ViewWorld[0][2] * TE.z + ViewWorld[0][3]) * BonesScaling * WideAngle;
		Bonesy = HeightAngle - (ViewWorld[1][0] * TE.x + ViewWorld[1][1] * TE.y + ViewWorld[1][2] * (TE.z + 13) + ViewWorld[1][3]) * BonesScaling * HeightAngle;
		Bonesy2 = HeightAngle - (ViewWorld[1][0] * TE.x + ViewWorld[1][1] * TE.y + ViewWorld[1][2] * (TE.z - 69) + ViewWorld[1][3]) * BonesScaling * HeightAngle;
		BonesBoxH = (Bonesy2 - Bonesy);
		BonesBoxW = BonesBoxH * 0.526515151552;
		EnemySightDistance = Take_CollimatorDistance(WideAngle, HeightAngle, Bonesx, Bonesy);
		EnemyDistance = floor(Take_EnemyDistance(M, TE) / 10);

		EnemyD3dDistance= floor(Take_EnemyDistance(M, D) / 10);
		EnemySideDis = EnemyD3dDistance - EnemyDistance;
		//sprintf(buf, "敌人的坐标距离：%f", EnemyD3dDistance);
		sprintf(buf2, "血量：%d", EnemyHealth);
		sprintf(buf3, "%f", (EnemyD3dDistance-EnemyDistance));
		if ((EnemyCamp == myteam) || (EnemyHealth <= 1) || (EnemySideDis > 1.f)|| (EnemySideDis < -1.f)) continue;
		//Dw.DrawBox_(x[j] - boxW[j] / 2, y2[j], boxW[j], boxH[j], 2, red);
		Dw.DrawBox_(Bonesx - BonesBoxW / 2, Bonesy, BonesBoxW, BonesBoxH, 2, blue);
		//DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 15, 13);
		//DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 13, 1);
		//DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 13, 30);
		//DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 30, 31);
		//DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 13, 17);
		//DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 17, 18);
		//DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 1, 3);
		//DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 3, 5);
		//DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 1, 7);
		//DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 7, 9);
		//Dw.DrawText_(Bonesx - BonesBoxW / 2, Bonesy - 20, buf, red);
		Dw.DrawText_(Bonesx - BonesBoxW / 2, Bonesy - 40, buf2, red);
		Dw.DrawText_(Bonesx - BonesBoxW / 2, Bonesy - 70, buf3, red);
		if (autoAim)
		{
			if (AimSize > EnemySightDistance)
			{
				AimSize = EnemySightDistance;
				Aiminfo = TE;
				AimMose = Aim(M, Aiminfo);
				if (EnemyHealth > 0 && (EnemyCamp != myteam))
				{
					if (GetKeyState(VK_LBUTTON) & 0x800) {
						DWORD wu;
						DWORD re = -1;
						WriteProcessMemory(proHandle, (LPVOID)((DWORD)engineHandle + 0x4622CC), (LPCVOID)&AimMose.y, sizeof(float), NULL);
						WriteProcessMemory(proHandle, (LPVOID)((DWORD)engineHandle + 0x4622CC + 4), (LPCVOID)&AimMose.x, sizeof(float), NULL);
						ReadProcessMemory(proHandle,(LPCVOID)(engineHandle+ 0X620154), &wu,sizeof(DWORD), NULL);
						if(wu!=0)
							WriteProcessMemory(proHandle, (LPVOID)((DWORD)mBase + 0x15D0), (LPCVOID)&re, sizeof(DWORD), NULL);
					}
				}
			}
		}
	}

	//Dw.DrawStart();
	//for (int j = 0; j < enemiesNum; j++)
	//{
	//	//Dw.DrawBox_(20, 100, 160, 200, 2, red);
	//	if ((EnemyCamp == myteam) || (EnemyHealth < 0)) continue;
	//	//Dw.DrawBox_(x[j] - boxW[j] / 2, y2[j], boxW[j], boxH[j], 2, red);
	//	Dw.DrawBox_(Bonesx - BonesBoxW / 2, Bonesy, BonesBoxW, BonesBoxH, 2, blue);
	//	DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 15, 13);
	//	DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 13, 1);
	//	DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 13, 30);
	//	DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 30, 31);
	//	DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 13, 17);
	//	DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 17, 18);
	//	DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 1, 3);
	//	DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 3, 5);
	//	DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 1, 7);
	//	DrawBonesL(ViewWorld, clientenemDrawBonesLBase, 7, 9);
	//	
	//}
	Dw.DrawEnd();

}



void DrawBonesL(float ViewWorld[4][4], int addr, int start, int end)
{
	int startDrawBonesL = addr + (start - 1) * 48 + 12;
	int endDrawBonesL;
	D3D DrawBonesL{};
	float gz, gx, gy, endy, endx, scaling1;
	ReadProcessMemory(proHandle, (LPCVOID)(DWORD)startDrawBonesL, &DrawBonesL.x, sizeof(float), NULL);
	ReadProcessMemory(proHandle, (LPCVOID)((DWORD)startDrawBonesL + 16), &DrawBonesL.y, sizeof(float), NULL);
	ReadProcessMemory(proHandle, (LPCVOID)((DWORD)startDrawBonesL + 32), &DrawBonesL.z, sizeof(float), NULL);
	//开始
	gz = ViewWorld[2][0] * DrawBonesL.x + ViewWorld[2][1] * DrawBonesL.y + ViewWorld[2][2] * DrawBonesL.z + ViewWorld[2][3];
	scaling1 = 1 / gz;
	if ((gz < 0)) return;
	gx = WideAngle + (ViewWorld[0][0] * DrawBonesL.x + ViewWorld[0][1] * DrawBonesL.y + ViewWorld[0][2] * DrawBonesL.z + ViewWorld[0][3]) * scaling1 * WideAngle;
	gy = HeightAngle - (ViewWorld[1][0] * DrawBonesL.x + ViewWorld[1][1] * DrawBonesL.y + ViewWorld[1][2] * DrawBonesL.z + ViewWorld[1][3]) * scaling1 * HeightAngle;

	//结束
	endDrawBonesL = addr + (end - 1) * 48 + 12;
	ReadProcessMemory(proHandle, (LPCVOID)(DWORD)endDrawBonesL, &DrawBonesL.x, sizeof(float), NULL);
	ReadProcessMemory(proHandle, (LPCVOID)((DWORD)endDrawBonesL + 16), &DrawBonesL.y, sizeof(float), NULL);
	ReadProcessMemory(proHandle, (LPCVOID)((DWORD)endDrawBonesL + 32), &DrawBonesL.z, sizeof(float), NULL);
	gz = ViewWorld[2][0] * DrawBonesL.x + ViewWorld[2][1] * DrawBonesL.y + ViewWorld[2][2] * DrawBonesL.z + ViewWorld[2][3];
	if ((gz < 0)) return;
	scaling1 = 1 / gz;
	endx = WideAngle + (ViewWorld[0][0] * DrawBonesL.x + ViewWorld[0][1] * DrawBonesL.y + ViewWorld[0][2] * DrawBonesL.z + ViewWorld[0][3]) * scaling1 * WideAngle;
	endy = HeightAngle - (ViewWorld[1][0] * DrawBonesL.x + ViewWorld[1][1] * DrawBonesL.y + ViewWorld[1][2] * DrawBonesL.z + ViewWorld[1][3]) * scaling1 * HeightAngle;
	Dw.DrawLine_(gx, gy, endx, endy, 2, red);
}

/// <summary>
///  绘制圆弧 
/// TODO 待完成
/// </summary>
/// <param name="ViewWorld"></param>
/// <param name="addr"></param>
/// <param name="Head"></param>
void  DrawBonesO(float ViewWorld[4][4], int addr, int Head)
{
	D3D BonesD;
	float z, HeadX, HeadY, HeadY2, BonesScaling;
	int startDrawBonesL = addr + (Head - 1) * 48 + 12;
	ReadProcessMemory(proHandle, (LPCVOID)(DWORD)startDrawBonesL, &BonesD.x, sizeof(float), NULL);
	ReadProcessMemory(proHandle, (LPCVOID)((DWORD)startDrawBonesL + 16), &BonesD.y, sizeof(float), NULL);
	ReadProcessMemory(proHandle, (LPCVOID)((DWORD)startDrawBonesL + 32), &BonesD.z, sizeof(float), NULL);
	z = ViewWorld[2][0] * BonesD.x + ViewWorld[2][1] * BonesD.y + ViewWorld[2][2] * BonesD.z + ViewWorld[2][3];
	if ((z < 0)) return;
	BonesScaling = 1 / z;
	HeadX = WideAngle + (ViewWorld[0][0] * BonesD.x + ViewWorld[0][1] * BonesD.y + ViewWorld[0][2] * BonesD.z + ViewWorld[0][3]) * BonesScaling * WideAngle;
	HeadY = HeightAngle - (ViewWorld[1][0] * BonesD.x + ViewWorld[1][1] * BonesD.y + ViewWorld[1][2] * BonesD.z + ViewWorld[1][3]) * BonesScaling * HeightAngle;
	HeadY2 = HeightAngle - (ViewWorld[1][0] * BonesD.x + ViewWorld[1][1] * BonesD.y + ViewWorld[1][2] * (BonesD.z - 70) + ViewWorld[1][3]) * BonesScaling * HeightAngle;
	//Dw.DrawText_(HeadX, HeadY - 10, "*", red);
}


void BaseInit()
{
	RECT rctA;
	ServerHandle = (HMODULE)GetModuleBaseAddress(L"server.dll", PID);
	engineHandle = (HMODULE)GetModuleBaseAddress(L"engine.dll", PID);
	proHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);
	clientHandle = (HMODULE)GetModuleBaseAddress(L"client.dll", PID);
	//MatrixBase = (DWORD)engineHandle + 0x590BEC;//
	MatrixBase = (DWORD)engineHandle + 0x596EF0;
	autoAim = true;
}

void start()
{
	han = FindWindow(NULL, L"Counter-Strike Source");
	if (han == NULL) return;
	GetWindowThreadProcessId(han, &PID);
	BaseInit();
	Dw.CreateTransWindows(han, Draws);
	Dw.WinMsgLoop();
}

int main()
{
	CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start, NULL, 0, NULL);
	getchar();
}




